import { makeAutoObservable } from 'mobx'
import { PermissionCode } from '../types'
import { getRSAResult } from '../uitls/common'
import { OutUserVO } from '../api/globals'

// 用户信息接口

class UserStore {
  // 用户登录状态
  isLoggedIn: boolean = false
  // 用户信息
  userInfo: OutUserVO | null = null
  // 权限码列表
  perms: PermissionCode[] = []
  // 加载状态
  loading: boolean = false

  tk: string | null = null

  // 用于跟踪用户信息是否已初始化的Promise
  private initPromise: Promise<void> | null = null

  constructor() {
    makeAutoObservable(this)
    // 初始化时从localStorage读取登录状态
    this.isLoggedIn = localStorage.getItem('isLoggedIn') === 'true'
    this.tk = localStorage.getItem('tk') ?? 'tk'
    // 如果已登录，初始化用户信息
    if (this.isLoggedIn) {
      this.initUserInfo()
    }
  }

  // 初始化用户信息，返回Promise以便等待完成
  initUserInfo(): Promise<void> {
    // 如果已经有初始化Promise，直接返回
    if (this.initPromise) {
      return this.initPromise
    }

    // 如果未登录，返回已解决的Promise
    if (!this.isLoggedIn) {
      return Promise.resolve()
    }

    // 创建并存储初始化Promise
    this.initPromise = this.fetchUserInfo()
    return this.initPromise
  }

  // 设置登录状态
  setIsLoggedIn(status: boolean) {
    this.isLoggedIn = status
    localStorage.setItem('isLoggedIn', JSON.stringify(status))
  }

  // 设置用户信息
  setUserInfo(userInfo: OutUserVO | null) {
    this.userInfo = userInfo
  }

  // 设置加载状态
  setLoading(status: boolean) {
    this.loading = status
  }

  setTk(tk: string | null) {
    this.tk = tk
    localStorage.setItem('tk', tk ?? 'tk')
  }

  setPerms(perms: PermissionCode[]) {
    this.perms = perms
  }

  // 模拟登录请求
  async login(
    username: string,
    password: string,
    code: string,
    img_code: string
  ): Promise<{ success: boolean; error?: { code: number; msg: string } }> {
    this.setLoading(true)

    const encryptedPwd = getRSAResult(password)
    try {
      const res = await Apis.auth.LoginUnitePassword({
        data: { username, password: encryptedPwd, code },
        headers: { img_code },
      })

      const { tk } = res
      this.setTk(tk ?? null)

      // 简单的用户名密码验证（实际项目中应该由后端验证）
      this.setIsLoggedIn(true)
      // 登录成功后获取用户信息，但不重复调用fetchUserInfo
      // 而是通过initUserInfo确保只调用一次
      await this.initUserInfo()
      return { success: true }
      // return { success: false, error }
    } catch (error) {
      const err = error as { code: number; msg: string }
      console.error('登录失败:', err)
      return { success: false, error: err }
    } finally {
      this.setLoading(false)
    }
  }

  // 登出
  logout() {
    this.setIsLoggedIn(false)
    this.setUserInfo(null)
    // 跳转到登录页
    window.location.href = '/ygym/login'
  }

  // 用于防止短时间内重复调用fetchUserInfo的标志
  private isFetchingUserInfo: boolean = false
  // 上次获取用户信息的时间戳
  private lastFetchTime: number = 0
  // 获取用户信息的最小间隔时间（毫秒）
  private readonly MIN_FETCH_INTERVAL: number = 2000 // 2秒

  // 获取用户信息
  async fetchUserInfo(): Promise<void> {
    // 如果正在获取用户信息，直接返回
    if (this.isFetchingUserInfo) {
      console.log('已有一个获取用户信息的请求正在进行中，跳过重复请求')
      return
    }

    // 检查是否在短时间内重复调用
    const now = Date.now()
    if (now - this.lastFetchTime < this.MIN_FETCH_INTERVAL) {
      console.log(
        `距离上次获取用户信息不足${this.MIN_FETCH_INTERVAL}ms，跳过重复请求`
      )
      return
    }

    this.isFetchingUserInfo = true
    this.setLoading(true)

    try {
      // 更新最后获取时间
      this.lastFetchTime = Date.now()

      // 确保Apis已经初始化
      await import('../uitls/apiUtils').then(({ waitForApisInitialized }) => {
        return waitForApisInitialized()
      })

      // 发起API请求
      const res = await Apis.auth.Tk({
        headers: {
          tk: this.tk,
        },
      })
      console.log('用户信息:', res)
      // this.setUserInfo(mockUserInfo)
      this.setUserInfo(res.userVO ?? null)
      this.setPerms((res.perms ?? []) as PermissionCode[])
    } catch (error) {
      console.error('获取用户信息失败:', error)
      // 如果获取用户信息失败，可能需要登出
      this.logout()
    } finally {
      this.isFetchingUserInfo = false
      this.setLoading(false)
    }
  }

  // 检查权限
  checkPermission(requiredPermission: string): boolean {
    if (!this.isLoggedIn || !this.userInfo) {
      return false
    }

    return this.perms.includes(requiredPermission as PermissionCode)
  }
}

export default new UserStore()
